package com.zzh.lib.core.utils;

import android.app.Activity;
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.DisplayMetrics;
import android.util.SparseArray;
import android.util.SparseIntArray;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowInsets;
import android.view.WindowManager;
import android.widget.TextView;

import androidx.core.content.res.ResourcesCompat;

import com.zzh.lib.bar.extension.ContextKt;
import com.zzh.lib.bar.extension.GlobalKt;
import com.zzh.lib.core.HLibrary;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by Administrator.
 *
 * @date: 2019/10/16
 * @email: zzh_hz@126.com
 * @QQ: 1299234582
 * @author: zzh
 * @description: 资源操作工具类
 * @since 1.0
 */
public class HResUtils {

    public static final String XIAOMI_FULLSCREEN_GESTURE = "force_fsg_nav_bar";
    public static final String XIAOMI_BRAND = "Xiaomi";
    public static final String VIVO_BRAND = "vivo";
    public static final String MEIZU_BRAND = "Meizu";
    public static final String HUAWEI_BRAND = "HUAWEI";

    final static SparseArray<String> strCache;
    final static SparseIntArray colorCache;
    final static SparseArray<Float> dimenCache;
    final static SparseIntArray intCache;
    final static Map<String, Integer> colorStrCache;

    static {
        strCache = new SparseArray<>();
        colorCache = new SparseIntArray();
        dimenCache = new SparseArray<>();
        intCache = new SparseIntArray();
        colorStrCache = new ConcurrentHashMap<>();
    }

    /**
     * 获取字符串资源
     *
     * @param resId 字符串资源的ids
     * @return 字符串
     */
    public static String getString(int resId) {
        String strRes = strCache.get(resId, "");
        if (TextUtils.isEmpty(strRes)) {
            String value = HLibrary.getAppContext().getString(resId);
            strCache.put(resId, value);
            return value;
        }
        return strRes;
    }

    /**
     * 获取int值
     *
     * @param resId res id
     * @return int资源值
     */
    public static int getInteger(int resId) {

        int integer = intCache.get(resId, -1);
        if (integer == -1 || integer == 0) {
            integer = HLibrary.getInstance().getContext().getResources().getInteger(resId);
            intCache.put(resId, integer);
            return integer;
        }
        return integer;

    }


    /**
     * 获取字符串资源
     *
     * @param resId 资源ids
     * @param args  参数
     * @return 字符串
     */
    public static String getString(int resId, Object... args) {
        return HLibrary.getInstance().getContext().getString(resId, args);
    }

    /**
     * 获取资源文件中的颜色
     *
     * @param colorRes 颜色ID
     * @return 颜色值
     */
    public static int parseColor(String colorRes) {
        Integer value = colorStrCache.get(colorRes);
        if (value == null || value <= 0) {
            int color = Color.parseColor(colorRes);
            colorStrCache.put(colorRes, color);
            return color;
        }
        return value;
    }

    /**
     * 获取资源文件中的颜色
     *
     * @param colorRes 颜色ID
     * @return 颜色值
     */
    public static int getIntColor(int colorRes) {
        int value = colorCache.get(colorRes, -1);
        if (value <= 0) {
            int color = HLibrary.getInstance().getContext().getResources().getColor(colorRes);
            colorCache.put(colorRes, color);
            return color;
        }
        return value;
    }

    /**
     * @param resId 资源id
     * @return 资源id指向的具体值
     */
    public static float getDimension(int resId) {
        Float value = dimenCache.get(resId, -1f);
        if (value == null || value <= 0) {
            float dimension = HLibrary.getInstance().getContext().getResources().getDimension(resId);
            dimenCache.put(resId, dimension);
            return dimension;
        }
        return value;
    }

    /**
     * @param resId 资源id
     * @return 资源id指向的舍去小数的值
     * @link HResUtils.getDimensionPixelOffset(resId)
     */
    public static int getDimensionPixelOffset(int resId) {
        return HLibrary.getInstance().getContext().getResources().getDimensionPixelOffset(resId);
    }

    /**
     * @param resId 资源id
     * @return 资源id指向的四舍五入之后的值
     * @link HResUtils.getDemension(resId)
     */
    public static int getDimensionPixelSize(int resId) {
        return HLibrary.getInstance().getContext().getResources().getDimensionPixelSize(resId);
    }

    /**
     * 获取资源id
     *
     * @param name       资源的名称
     * @param defType    类型：比如mipmap,drawable
     * @param defPackage 包名
     * @return 本资源指向的id
     */
    public static int getIdentifier(String name, String defType, String defPackage) {
        try {
            return HLibrary.getInstance().getContext().getResources().getIdentifier(name, defType, defPackage);
        } catch (Exception var4) {
            var4.printStackTrace();
            return 0;
        }
    }

    /**
     * 获取drawable 文件夹下的资源
     *
     * @param name 资源的名称。默认获取drawable文件夹下的文件
     * @return 本资源指向的id
     */
    public static int getIdentifierDrawable(String name) {
        return getIdentifier(name, "drawable", HLibrary.getInstance().getContext().getPackageName());
    }

    /**
     * @return status bar的高
     * @see HResUtils#getStatusBarHeight(Context)
     */
    public static int getStatusBarHeight() {
        return getStatusBarHeight(HLibrary.getInstance().getContext());
    }

    /**
     * 获取手机status bar的高度
     *
     * @param ctx 当前上下文
     * @return status bar的高
     * @see HResUtils#getStatusBarHeight
     */
    public static int getStatusBarHeight(Context ctx) {
        int height = 0;
        int resourceId = ctx.getResources().getIdentifier("status_bar_height", "dimen", "android");
        if (resourceId > 0) {
            height = HLibrary.getInstance().getContext().getResources().getDimensionPixelSize(resourceId);
        }
        return height;
    }

    /**
     * @return ActionBar的高度
     * @see HResUtils#getActionBarHeight(Context)
     */
    public static int getActionBarHeight() {
        return getActionBarHeight(HLibrary.getInstance().getContext());
    }

    /**
     * 获取ActionBar的高度
     *
     * @param ctx 上下文变量
     * @return ActionBar的高度
     * @see HResUtils#getActionBarHeight()
     */
    public static int getActionBarHeight(Context ctx) {
        TypedArray actionbarSizeTypedArray = ctx.obtainStyledAttributes(new int[]{android.R.attr.actionBarSize});
        float actionBarHeight = actionbarSizeTypedArray.getDimension(0, 0);
        actionbarSizeTypedArray.recycle();
        return (int) actionBarHeight;
    }

    /**
     * 获取底部导航栏高度.
     * 1.未支持全面屏时，手机厂商自己适配的导航栏
     * 2、ASOP
     *
     * @param activity 当前页面
     * @return Nav Bar 的高度
     */
    public static int getNavBarHeight(Activity activity) {
        if (activity == null) {
            activity = HLibrary.getLastActivity();
        }
        if (activity == null) {
            return 0;
        }


        if (ContextKt.commonNavigationBarExist(activity)) {
            return getNavBarHeightInternal(activity);
        } else {
            return 0;
        }
    }

    public static int getNavBarHeightInternal(Activity activity) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowManager wm = (WindowManager) HLibrary.getAppContext().getSystemService(Context.WINDOW_SERVICE);
            return wm.getCurrentWindowMetrics().getWindowInsets().getInsets(WindowInsets.Type.navigationBars()).bottom;
        }
        int navigationBarHeight = 0;
        Resources resources = HLibrary.getInstance().getContext().getResources();
        int resourceId = resources.getIdentifier(isPortrait(activity) ? "navigation_bar_height" : "navigation_bar_height_landscape", "dimen", "android");
        LogUtils.d("-------NAV BAR--resourceId: " + resourceId);
        if (resourceId > 0 && checkDeviceHasNavBar(activity) && isNavigationBarVisible(activity)) {
            navigationBarHeight = resources.getDimensionPixelSize(resourceId);
        }
        return navigationBarHeight;
    }

    /**
     * @return Nav Bar 的高度
     * @see HResUtils#getNavBarHeight(Activity)
     */
    public static int getNavBarHeight() {
        return getNavBarHeight(HLibrary.getLastActivity());
    }

    /**
     * Return whether the navigation bar visible.
     * <p>Call it in onWindowFocusChanged will get right result.</p>
     *
     * @param activity The activity.
     * @return {@code true}: yes<br>{@code false}: no
     */
    public static boolean isNavBarVisible(final Activity activity) {
        return isNavBarVisible(activity.getWindow());
    }

    /**
     * Return whether the navigation bar visible.
     * <p>Call it in onWindowFocusChanged will get right result.</p>
     *
     * @param window The window.
     * @return {@code true}: yes<br>{@code false}: no
     */
    public static boolean isNavBarVisible(final Window window) {
        boolean isVisible = false;
        ViewGroup decorView = (ViewGroup) window.getDecorView();
        for (int i = 0, count = decorView.getChildCount(); i < count; i++) {
            final View child = decorView.getChildAt(i);
            final int id = child.getId();
            if (id != View.NO_ID) {
                String resourceEntryName = getResNameById(id);
                if ("navigationBarBackground".equals(resourceEntryName)
                        && child.getVisibility() == View.VISIBLE) {
                    isVisible = true;
                    break;
                }
            }
        }
        if (isVisible) {
            // 对于三星手机，android10以下非OneUI2的版本，比如 s8，note8 等设备上，
            // 导航栏显示存在bug："当用户隐藏导航栏时显示输入法的时候导航栏会跟随显示"，会导致隐藏输入法之后判断错误
            // 这个问题在 OneUI 2 & android 10 版本已修复
            if (HDeviceUtils.isSamsung() && Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
                try {
                    return Settings.Global.getInt(HLibrary.getAppContext().getContentResolver(), "navigationbar_hide_bar_enabled") == 0;
                } catch (Exception ignore) {
                }
            }

            int visibility = decorView.getSystemUiVisibility();
            isVisible = (visibility & View.SYSTEM_UI_FLAG_HIDE_NAVIGATION) == 0;
        }

        return isVisible;
    }


    private static String getResNameById(int id) {
        try {
            return HLibrary.getAppContext().getResources().getResourceEntryName(id);
        } catch (Exception ignore) {
            return "";
        }
    }

    /**
     * 获取资源
     *
     * @param resId 图片资源ID
     * @return drawable 资源
     */
    public static Drawable getDrawable(int resId) {
        return getDrawable(resId, null);
    }

    public static Drawable getDrawable(int resId, Resources.Theme theme) {
        return ResourcesCompat.getDrawable(HLibrary.getInstance().getContext().getResources(), resId, theme);
    }

    /**
     * 手机具有底部导航栏时，底部导航栏是否可见
     * 在小米手机上小米8、小米MIX系列全面屏无效，隐藏虚拟按键仍旧返回true
     *
     * @param activity 判断导航栏是否可见
     * @return true 可见
     */
    public static boolean isNavigationBarVisible(Activity activity) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            WindowManager wm = (WindowManager) HLibrary.getAppContext().getSystemService(Context.WINDOW_SERVICE);
            return wm.getCurrentWindowMetrics().getWindowInsets().getInsets(WindowInsets.Type.systemBars()).bottom > 0;
        }


        if (XIAOMI_BRAND.equalsIgnoreCase(HDeviceUtils.getDeviceBrand())) {
            int val = Settings.Global.getInt(activity.getContentResolver(), XIAOMI_FULLSCREEN_GESTURE, 0);
            LogUtils.d("--------nav bar show: " + val);
            return val == 0;
        } else {
            boolean show = false;
            Display display = activity.getWindow().getWindowManager().getDefaultDisplay();
            Point point = new Point();
            Point v = new Point();
            display.getRealSize(point);
            display.getSize(v);
            View decorView = activity.getWindow().getDecorView();
            Configuration conf = activity.getResources().getConfiguration();
            if (Configuration.ORIENTATION_LANDSCAPE == conf.orientation) {
                View contentView = decorView.findViewById(android.R.id.content);
                if (contentView != null) {
                    show = (point.x != contentView.getWidth());
                }
            } else {
                Rect rect = new Rect();
                decorView.getWindowVisibleDisplayFrame(rect);
                show = (Math.abs(rect.bottom - point.y) > 80);
            }
            LogUtils.d("--------nav bar show: " + show);
            return show;
        }
    }

    /**
     * @see HResUtils#isNavigationBarVisible(Activity)
     */
    public static boolean isNavigationBarVisible() {
        return isNavigationBarVisible(HLibrary.getLastActivity());
    }

    /**
     * 检测是否具有底部导航栏
     *
     * @param activity 当前activity
     * @return true 具有底部导航栏
     */
    public static boolean checkDeviceHasNavBar(Activity activity) {
        WindowManager windowManager = activity.getWindowManager();
        Display display = windowManager.getDefaultDisplay();
        DisplayMetrics realDisplayMetrics = new DisplayMetrics();
        display.getRealMetrics(realDisplayMetrics);
        int realHeight = realDisplayMetrics.heightPixels;
        int realWidth = realDisplayMetrics.widthPixels;
        DisplayMetrics displayMetrics = new DisplayMetrics();
        display.getMetrics(displayMetrics);
        int displayHeight = displayMetrics.heightPixels;
        int displayWidth = displayMetrics.widthPixels;
        return (realWidth - displayWidth) > 0 || (realHeight - displayHeight) > 0;
    }

    /**
     * @return 检测是否有nav bar
     * @see HResUtils#checkDeviceHasNavBar(Activity)
     */
    public static boolean checkDeviceHasNavBar() {
        return checkDeviceHasNavBar(HLibrary.getLastActivity());
    }

    /**
     * 是否为竖屏
     */
    public static boolean isPortrait(Context activity) {
        return activity.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT;
    }


    /**
     * @see HResUtils#getDisplayWidth(Context)
     */
    public static int getDisplayWidth() {
        return getDisplayWidth(HLibrary.getInstance().getContext());
    }

    /**
     * 获取屏幕的宽度
     *
     * @return 屏幕宽度
     */
    public static int getDisplayWidth(Context ctx) {
        DisplayMetrics dm = ctx.getApplicationContext().getResources().getDisplayMetrics();
        return dm.widthPixels;
    }

    /**
     * @see HResUtils#getDisplayHeight(Context)
     */
    public static int getDisplayHeight() {
        return getDisplayHeight(HLibrary.getInstance().getContext());//获取宽度
    }

    /**
     * 获取手机屏幕真实的高度。一般获取手机屏幕的高度是真实手机长度减去状态栏的高度。
     * getRealMetrics 这个方法是API 17之后才有的，之前的使用@hide 来标记的，并不对外开放API，
     * 所以API 小于 17使用反射的方法取得屏幕的真实高度.
     * WindowManager.getDefaultDisplay().getRealMetrics(DisplayMetrics); 方法在Android 11(Build.VERSION_CODES.R)上，已经标记废弃，建议使用
     * wm.getCurrentWindowMetrics().getWindowInsets().getInsets(WindowInsets.Type.systemBars()) 方法获取Insets实例，bottom是
     *
     * @param ctx 上下文
     * @return 屏幕高度
     */
    public static int getDisplayHeight(Context ctx) {
        WindowManager wm = (WindowManager) ctx.getSystemService(Context.WINDOW_SERVICE);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            return wm.getCurrentWindowMetrics().getBounds().bottom;
        } else {
            DisplayMetrics dm = new DisplayMetrics();
            wm.getDefaultDisplay().getRealMetrics(dm);
            return dm.heightPixels;
        }
    }

    /**
     * @param px 像素
     * @return 返回值单位是dp
     */
    public static int px2dp(float px) {
        float scale = HLibrary.getInstance().getContext().getResources().getDisplayMetrics().density;
        return (int) (px / scale + 0.5f);
    }

    /**
     * @param dp dp值
     * @return 返回像素值
     */
    public static int dp2px(float dp) {
        float scale = HLibrary.getInstance().getContext().getResources().getDisplayMetrics().density;
        return (int) (dp * scale + 0.5f);
    }

    /**
     * @param px 像素
     * @return 返回值单位是dp
     */
    public static int px2sp(float px) {
        final float fontScale = HLibrary.getInstance().getContext().getResources().getDisplayMetrics().scaledDensity;
        return (int) (px / fontScale + 0.5f);
    }

    /**
     * @param sp 字体大小
     * @return 返回字体像素值
     */
    public static int sp2px(float sp) {
        final float fontScale = HLibrary.getInstance().getContext().getResources().getDisplayMetrics().scaledDensity;
        return (int) (fontScale * sp + 0.5);
    }

    public static void drawableNull(TextView tv) {
        if (tv == null) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
    }

    public static void drawableNull(TextView tv, Drawable left, Drawable top, Drawable right, Drawable bottom) {

        if (tv == null) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(left, top, right, bottom);
    }

    public static void drawableTop(TextView tv, int drawableRes) {

        if (tv == null || drawableRes == 0) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(0, drawableRes, 0, 0);
    }

    public static void drawableLeft(TextView tv, int drawableRes) {

        if (tv == null || drawableRes == 0) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(drawableRes, 0, 0, 0);
    }

    public static void drawableRight(TextView tv, int drawableRes) {

        if (tv == null || drawableRes == 0) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, drawableRes, 0);
    }

    public static void drawableBottom(TextView tv, int drawableRes) {

        if (tv == null || drawableRes == 0) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, drawableRes);
    }

    public static void drawableTop(TextView tv, Drawable drawable) {

        if (tv == null) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(null, drawable, null, null);
    }

    public static void drawableLeft(TextView tv, Drawable drawable) {

        if (tv == null) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
    }

    public static void drawableRight(TextView tv, Drawable drawable) {
        if (tv == null) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(null, null, drawable, null);
    }

    public static void drawableBottom(TextView tv, Drawable drawable) {

        if (tv == null) {
            return;
        }
        tv.setCompoundDrawablesWithIntrinsicBounds(null, null, null, drawable);
    }
}
